/**
 * $Id: CellPath.java,v 1.6 2009/11/17 14:36:09 gaudenz Exp $
 * Copyright (c) 2007, Gaudenz Alder
 */
package com.magnificent.graph.model;

import java.util.StringTokenizer;
import java.util.regex.Pattern;

/**
 * Implements a mechanism for temporary cell Ids.
 */
public class CellPath {

    /**
     * Defines the separator between the path components. Default is
     * <code>.</code>.
     */
    public static String PATH_SEPARATOR = ".";

    /**
     * Creates the cell path for the given cell. The cell path is a
     * concatenation of the indices of all cells on the (finite) path to
     * the root, eg. "0.0.0.1".
     *
     * @param cell Cell whose path should be returned.
     * @return Returns the string that represents the path.
     */
    public static String create(mxICell cell) {
        String result = "";

        if (cell != null) {
            mxICell parent = cell.getParent();

            while (parent != null) {
                int index = parent.getIndex(cell);
                result = index + CellPath.PATH_SEPARATOR + result;

                cell = parent;
                parent = cell.getParent();
            }
        }

        return (result.length() > 1) ? result.substring(0, result.length() - 1)
                : "";
    }

    /**
     * Returns the path for the parent of the cell represented by the given
     * path. Returns null if the given path has no parent.
     *
     * @param path Path whose parent path should be returned.
     */
    public static String getParentPath(String path) {
        if (path != null) {
            int index = path.lastIndexOf(CellPath.PATH_SEPARATOR);

            if (index >= 0) {
                return path.substring(0, index);
            } else if (path.length() > 0) {
                return "";
            }
        }

        return null;
    }

    /**
     * Returns the cell for the specified cell path using the given root as the
     * root of the path.
     *
     * @param root Root cell of the path to be resolved.
     * @param path String that defines the path.
     * @return Returns the cell that is defined by the path.
     */
    public static mxICell resolve(mxICell root, String path) {
        mxICell parent = root;
        String[] tokens = path.split(Pattern.quote(PATH_SEPARATOR));

        for (int i = 0; i < tokens.length; i++) {
            parent = parent.getChildAt(Integer.parseInt(tokens[i]));
        }

        return parent;
    }

    /**
     * Compares the given cell paths and returns -1 if cp1 is smaller, 0 if
     * cp1 is equal and 1 if cp1 is greater than cp2.
     */
    public static int compare(String cp1, String cp2) {
        StringTokenizer p1 = new StringTokenizer(cp1, CellPath.PATH_SEPARATOR);
        StringTokenizer p2 = new StringTokenizer(cp2, CellPath.PATH_SEPARATOR);
        int comp = 0;

        while (p1.hasMoreTokens() &&
                p2.hasMoreTokens()) {
            String t1 = p1.nextToken();
            String t2 = p2.nextToken();

            if (!t1.equals(t2)) {
                if (t1.length() == 0 ||
                        t2.length() == 0) {
                    comp = t1.compareTo(t2);
                } else {
                    comp = Integer.valueOf(t1).compareTo(Integer.valueOf(t2));
                }

                break;
            }
        }

        // Compares path length if both paths are equal to this point
        if (comp == 0) {
            int t1 = p1.countTokens();
            int t2 = p2.countTokens();

            if (t1 != t2) {
                comp = (t1 > t2) ? 1 : -1;
            }
        }

        return comp;
    }

}

  /* converted to utf8 */